#ifndef DIGEST_H
#define DIGEST_H


#include <string>
#include <sstream>
#include <vector>
#include <assert.h>
#include "ultoa.h"


//________________________________________________________________________________________

//	t_digest



//		Holds the results of a 128 bit message hash


//________________________________________________________________________________________
struct t_digest
{
	t_digest(unsigned* p)
				{digest[0]	= p[0];
				 digest[1]	= p[1];
				 digest[2]	= p[2];
				 digest[3]	= p[3];}
	t_digest(unsigned d1, unsigned d2, unsigned d3, unsigned d4)
				{digest[0]	= d1;
				 digest[1]	= d2;
				 digest[2]	= d3;
				 digest[3]	= d4;}
	t_digest()
				 {digest[0]	=
				  digest[1]	=
				  digest[2]	=
				  digest[3]	= 0;}
	bool operator !=(const t_digest& o) const	{return ! (o == *this);}
	bool operator ==(const t_digest& o) const ;
	bool operator <(const t_digest& o) const ;
	unsigned trunc_to32() const{return digest[0];}
	std::string str(char i = '_') const;
	std::string single_field_str() const;
	unsigned digest[4];
};

inline bool t_digest::operator ==(const t_digest& o) const
	{	return std::equal(o.digest, o.digest+ 4, digest);	}
inline bool t_digest::operator <(const t_digest& o) const
{
//	return std::lexicographical_compare(o.digest, o.digest+ 4, digest);
	// unrolled
	if (digest[0] < o.digest[0])
		return true;
	if (digest[0] > o.digest[0] )
		return false;
	if (digest[1] < o.digest[1])
		return true;
	if (digest[1] > o.digest[1] )
		return false;
	if (digest[2] < o.digest[2])
		return true;
	if (digest[2] > o.digest[2] )
		return false;
	return digest[3] < o.digest[3];
}

template <typename t_strm>
inline t_strm& operator << (t_strm& os, const t_digest& o)
{
	os << '['	<< o.digest[0] << ','
				<< o.digest[1] << ','
				<< o.digest[2] << ','
				<< o.digest[3] << ']';
	return os;
}

inline std::string t_digest::str(char i) const
{
	std::string ret;
	ultoa(digest[0], ret) += i;
	ultoa(digest[1], ret) += i;
	ultoa(digest[2], ret) += i;
	ultoa(digest[3], ret);
	return ret;
}

inline std::string& operator +=(std::string& ret, const t_digest& hash)
{
	ret						   += '{';
	ultoa(hash.digest[0], ret) += ',';
	ultoa(hash.digest[1], ret) += ',';
	ultoa(hash.digest[2], ret) += ',';
	ultoa(hash.digest[3], ret) += '}';
	return ret;
}


inline std::string t_digest::single_field_str() const
{
	std::string ret;
	ret += (*this);
	return ret;
}



#endif

